PercentageParser<Str>
使用法
code:ts
type PString1 = ''
type PString2 = '+85%'
type PString3 = '-85%'
type PString4 = '85%'
type PString5 = '85'
type R1 = PercentageParser<PString1> // expected '', ''
type R2 = PercentageParser<PString2> // expected "85", "%"
type R3 = PercentageParser<PString3> // expected "85", "%"
type R4 = PercentageParser<PString4> // expected "85", "%"
type R5 = PercentageParser<PString5> // expected "85", ""
文字列を引数にとって、符号、数字、単位に分ける
定義
code:ts
// prettier-ignore
type PercentageParser<Str extends string> =
Str extends ${Sign<Str>}${infer N}${Unit<Str>}
: never;
// prettier-ignore
type Sign<Str extends string>
= Str extends +${string} ? '+'
: Str extends -${string} ? '-'
: '';
type Unit<Str extends string>
= Str extends ${string}% ? '%'
: '';
ポイント
Str extends \`${Sign<Str>}${infer N}${Unit<Str>}\`の部分
unionで'+'|'-'|''とやっているわけではない
扱いづらいのはnumberの部分なのでそこを残す
infer N
前からと、後ろからパターンマッチを同時にやっている感じ
code:ts
// prettier-ignore
type PercentageParser<A extends string>
= A extends ${CheckPrefix<infer L>}${infer R}
: ...CheckSuffix<A>;
type CheckPrefix<T> = T extends '+' | '-' ? T : never;
type CheckSuffix<T> = T extends ${infer P}% ? P, '%' : T, ''; 記述量が少ない
先に符号だけわけて、後から残りを処理する
CheckPrefix<infer L>の部分がおもろいmrsekut.icon
こうすることで、パターンマッチに名前をつけてる感じのことをしている
普通に書いたらこうなるはず
code:ts
type PercentageParser<A extends string>
= A extends ${infer S}${infer R}
? S extends '+' | '-'
: ...CheckSuffix<A> // ①
: ...CheckSuffix<A>; // ②
type CheckSuffix<T> = T extends ${infer P}% ? P, '%' : T, ''; 文字列のパターンマッチでSを取り出した後に、
Sが'+'か'-'かをチェックすることになる
イメージこんな感じ
code:ts
type Hoge<A extends string>
= A extends ${T: '+'|'-'}${infer R}
? T
: never;
'+'|'-'にマッチさせつつ、Tという名前をつけている
でもそんな汎用性ないかmrsekut.icon
1文字しか無理だし